#include"w25q32.h"


void w25q32_init(void)
{
    spi_init();
}


void w25q32_id(uint8_t* mid,uint16_t * did)
{
    spi_start();

    spi_swapdata(0x9f);
    *mid=spi_swapdata(0xff);
    *did=0;
    *did|=spi_swapdata(0xff)<<8;
    *did|=spi_swapdata(0xff);

    spi_stop();
}

void w25q32_writeenable(void)
{
    spi_start();
    spi_swapdata(0x06);
    spi_stop();
}

void w25q32_writedisable(void)
{
    spi_start();
    spi_swapdata(0x04);
    spi_stop();
}

void w25q32_notbusy(void)
{
    spi_start();
    spi_swapdata(0x05);
    while (spi_swapdata(0xff)&0x01)
    {
    }
    spi_stop();
}

void w25q32_erase(uint32_t block,uint32_t secter)
{
    w25q32_notbusy();
    w25q32_writeenable();
    spi_start();
    uint32_t add=(block<<16)+(secter<<12); 
    spi_swapdata(0x20);

    spi_swapdata((add>>16) & 0xff);
    spi_swapdata((add>>8) & 0xff);
    spi_swapdata(add & 0xff);
    spi_stop();
    w25q32_writedisable();
    
}

void w25q32_writepage(uint32_t block,uint32_t secter,uint32_t page,uint8_t * data,uint16_t len)
{
    w25q32_notbusy();
    w25q32_writeenable();
    spi_start();
    spi_swapdata(0x02);

    uint32_t addr=(block<<16)+(secter<<12)+(page<<8);
    spi_swapdata((addr>>16) & 0xff);
    spi_swapdata((addr>>8) & 0xff);
    spi_swapdata( addr & 0xff);
    for (uint32_t i = 0; i < len; i++)
    {
        spi_swapdata(data[i]);
    }
    spi_stop();
    w25q32_writedisable();
}

void w25q32_read(uint32_t block,uint32_t secter,uint32_t page,uint32_t innearpage,uint8_t * data,uint16_t len)
{
    w25q32_notbusy();
    spi_start();
    spi_swapdata(0x03);

    uint32_t addr=(block<<16)+(secter<<12)+(page<<8)+innearpage;
    spi_swapdata((addr>>16) & 0xff);
    spi_swapdata((addr>>8) & 0xff);
    spi_swapdata( addr & 0xff);
    for (uint32_t i = 0; i < len; i++)
    {
        data[i]=spi_swapdata(0xff);
    }
    spi_stop();
}
